package com.untour.im.client.command;

import com.alibaba.fastjson2.TypeReference;
import com.untour.im.codec.constants.IMConstants;
import com.untour.im.codec.protocol.command.Command;
import com.untour.im.codec.protocol.message.body.MessageBody;
import com.untour.im.codec.protocol.packet.request.PacketData;
import com.untour.im.codec.protocol.packet.response.body.MessageResponsePacketData;
import com.untour.im.codec.protocol.packet.response.body.OfflineServerResponsePacketData;
import com.untour.im.codec.protocol.packet.response.header.ResponsePacketHeader;
import com.untour.im.codec.protocol.serialize.Serializer;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 发送消息转化类
 */
@Slf4j
public class ServerPacketDecodec {
    public static final ServerPacketDecodec INSTANCE = new ServerPacketDecodec();

    private final Map<Byte, TypeReference<? extends MessageBody>> packetTypeMap;

    private ServerPacketDecodec(){
        // 指令 和 对应的数据包类 映射
        packetTypeMap = new HashMap<>();
        packetTypeMap.put(Command.OFFLINE, IMConstants.OFFLINE_MESSAGE_TYPE_REFERENCE);
        packetTypeMap.put(Command.LOGIN_RESPONSE, IMConstants.LOGIN_RESPONSE_MESSAGE_TYPE_REFERENCE);
        packetTypeMap.put(Command.HEARTBEAT_RESPONSE, IMConstants.HEART_BEAT_MESSAGE_TYPE_REFERENCE);
        packetTypeMap.put(Command.SINGLE_MESSAGE_RECEIVE, IMConstants.SINGLE_TXT_MESSAGE_TYPE_REFERENCE);
        packetTypeMap.put(Command.GROUP_MESSAGE_RECEIVE, IMConstants.GROUP_TXT_MESSAGE_TYPE_REFERENCE);
        packetTypeMap.put(Command.MESSAGE_RESPONSE, IMConstants.TXT_MESSAGE_TYPE_REFERENCE);

    }
    private TypeReference<? extends MessageBody> getRequestType(byte command) {
        return packetTypeMap.get(command);
    }


    public PacketData<ResponsePacketHeader,MessageBody> decode(ByteBuf byteBuf) {

        /** 获取command*/
        byte command = byteBuf.readByte();

        /** 获取serializerType*/
        byte serializerType = byteBuf.readByte();

        /** 获取bodyLen*/
        int bodyLen = byteBuf.readInt();

        //判断数据长度完整
        if (byteBuf.readableBytes() < bodyLen) {
            byteBuf.resetReaderIndex();
            return null;
        }

        PacketData message;
        if(command == Command.OFFLINE){
            message = new OfflineServerResponsePacketData();
        } else {
            message = new MessageResponsePacketData();
        }

        ResponsePacketHeader responsePacketHeader = new ResponsePacketHeader();
        responsePacketHeader.setCommand(command);
        responsePacketHeader.setLength(bodyLen);
        responsePacketHeader.setMessageType(serializerType);
        message.setHeader(responsePacketHeader);

        //获取序列化类型
        Serializer serializer = SerializerCodec.getSerializer(serializerType);
        TypeReference<? extends MessageBody> requestType = this.getRequestType(command);
        //读取内容
        byte[] bodyData = new byte[bodyLen];
        byteBuf.readBytes(bodyData);

        if (serializer != null) {
            message.setMessageBody(serializer.deserialize(requestType, bodyData));
        } else {
            log.warn("无法解析包数据");
            message = null;
        }
        byteBuf.markReaderIndex();
        return message;
    }
}
